package Simcomp::Disk;
use strict;
use warnings;
use lib qw( ../ );
use Simcomp::Process;
use Simcomp::Result;
use Simcomp::Random;

our $VERSION = "0.01";

sub new
{
	my $class = shift;
	my %attr = @_;
	$attr{'state'} = "idle";
	$attr{'current_time'} = 0;
	$attr{'event_time'} = undef;
	$attr{'queue'} = [()];
	
	bless \%attr, $class;
	return \%attr;
	
}

sub set_name
{
	$_[0]->{'name'} = $_[1];
}

sub set_state
{
	$_[0]->{'state'} = $_[1];
}

sub name
{
	$_[0]->{'name'};
}

sub result
{
	$_[0]->{'result'};
}

sub state
{
	$_[0]->{'state'};
}

sub set_event_time
{
	$_[0]->{'event_time'} = $_[1];
}

sub event_time
{
	$_[0]->{'event_time'};
}

sub set_current_time
{
	$_[0]->{'current_time'} = $_[1];
}

sub current_time
{
	$_[0]->{'current_time'};
}

sub set_running_process
{
	$_[0]->{'running_process'} = $_[1];
}

sub running_process
{
	$_[0]->{'running_process'};
}

sub dist_info
{
    $_[0]->{'dist_info'};
}

sub receive_process
{
    my $self = shift;
    my $process = shift;
    $process->set_disk( $self->name );
    if ($self->{'state'} eq "running")
    {
	$self->add_to_queue($process);
    }
    elsif ($self->{'state'} eq "idle")
    {
	$self->{'state'} = "running";
	$self->set_running_process( $process );
	my $dist_gen = Simcomp::Random::getDistribution( $self->dist_info->{'type'} );
	my $time_in_disk = &$dist_gen(@{$self->dist_info->{'params'}});
	$process->set_time_in_disk( $time_in_disk );
	$self->set_event_time( $self->current_time + $time_in_disk ); 
    }
}

sub act
{
    my $self = shift;
    $self->{'running_process'}->set_time_out_disk( $self->event_time );
    $self->{'result'}->add_process( $self->running_process );
    if ( scalar @{ $self->{'queue'} } )
    {
	$self->set_running_process( $self->remove_from_queue );
	my $dist_gen = Simcomp::Random::getDistribution( $self->dist_info->{'type'} );
	my $time_in_disk = &$dist_gen( @{$self->dist_info->{'params'}});
	$self->{'running_process'}->set_time_in_disk( $time_in_disk );
	$self->set_event_time( $self->current_time + $time_in_disk  );
    }
    else
    {
	$self->set_running_process( undef );
	$self->set_event_time( undef );
	$self->set_state( 'idle' );
    }
      

}

sub add_to_queue
{
	my $self=shift;
	push @{$self->{'queue'}}, shift;
}

sub remove_from_queue
{
	my $self = shift;
	shift @{$self->{'queue'}};
}

sub feed_result
{
	my $self = shift;
	my $result = $self->result;
	my $queue_size = scalar @{ $self->{'queue'} };
	if ($self->name eq 'DISK_A')
	{
		$result->add_queue_size_in_disk_A($queue_size, $self->current_time);
		$result->add_diskA_state($self->state, $self->current_time);
	}
	elsif ($self->name eq 'DISK_B')
	{
		$result->add_queue_size_in_disk_B($queue_size, $self->current_time);
		$result->add_diskB_state($self->state, $self->current_time);
	}
}



